/**
 * src/pages/cart/index.tsx
 * ------------------------------------
 * 购物车页面组件
 * 1. 显示购物车中的商品列表和数量
 * 2. 支持商品数量调整和删除操作
 * 3. 集成积分系统，支持积分抵扣订单金额
 * 4. 提供订单备注功能
 * 5. 处理订单提交和支付流程
 * 6. 支持网络状态监控和离线模式
 * 该页面是用户下单前的最后确认页面
 * 创建日期：2025-08-06
 */
import React, { useState, useEffect } from 'react'
import { View, Text, Button, Image, ScrollView, Textarea } from '@tarojs/components'
import Taro from '@tarojs/taro'
import { useAppContext } from '../../store'
import { CloudDataManager } from '../../utils/cloud'
import { pointsUtils } from '../../utils/pointsUtils'
import { errorUtils, ErrorType } from '../../utils/errorHandler'
import NetworkStatus from '../../components/NetworkStatus'
import pointsConfig from '../../config/pointsConfig'
import './index.scss'

/**
 * 购物车页面组件
 * 提供购物车管理、积分抵扣、订单提交等功能
 */
const Cart: React.FC = () => {
  const { state, dispatch } = useAppContext()
  const [userPoints, setUserPoints] = useState(0)
  const [maxPointsForOrder, setMaxPointsForOrder] = useState(0)
  const [pointsToUse, setPointsToUse] = useState(0)
  const [usePoints, setUsePoints] = useState(false)
  const [note, setNote] = useState('')
  const [submitting, setSubmitting] = useState(false)
  const [isOnline, setIsOnline] = useState(true)
  
  // 计算商品总金额
  const totalAmount = state.cart.reduce((sum, item) => sum + item.totalPrice, 0)
  
  // 计算积分抵扣金额
  const pointsDiscount = pointsUtils.calculateDiscountAmount(pointsToUse)
  
  // 计算最终支付金额
  const finalAmount = Math.max(0, totalAmount - pointsDiscount)
  
  // 计算最大可用积分和抵扣金额
  const maxDiscount = pointsUtils.calculateDiscountAmount(maxPointsForOrder)
  
  // 初始化时获取用户积分
  useEffect(() => {
    if (state.currentUser) {
      fetchUserPoints()
    }
  }, [state.currentUser])
  
  // 当购物车或用户积分变化时，重新计算最大可用积分
  useEffect(() => {
    if (state.currentUser && userPoints > 0 && totalAmount > 0) {
      const maxPoints = pointsUtils.calculateMaxPointsForOrder(totalAmount, userPoints)
      setMaxPointsForOrder(maxPoints)
      setPointsToUse(maxPoints)
    } else {
      setMaxPointsForOrder(0)
      setPointsToUse(0)
      setUsePoints(false)
    }
  }, [totalAmount, userPoints, state.currentUser])
  
  /**
   * 获取用户当前积分
   * 从云端或本地存储获取用户积分信息
   */
  const fetchUserPoints = async () => {
    if (!state.currentUser) return
    
    try {
      const points = await pointsUtils.getUserPoints(state.currentUser.id)
      setUserPoints(points)
    } catch (error) {
      console.error('获取用户积分失败:', error)
      Taro.showToast({
        title: '获取积分信息失败',
        icon: 'none'
      })
    }
  }
  
  /**
   * 更新购物车中商品的数量
   * @param dishId 菜品ID
   * @param quantity 新的数量
   */
  const updateItemQuantity = (dishId: string, quantity: number) => {
    dispatch({
      type: 'UPDATE_CART_ITEM',
      payload: { dishId, quantity }
    })
  }
  
  /**
   * 从购物车中移除商品
   * @param dishId 要移除的菜品ID
   */
  const removeItem = (dishId: string) => {
    dispatch({
      type: 'REMOVE_FROM_CART',
      payload: dishId
    })
  }
  
  /**
   * 清空购物车
   * 显示确认对话框，用户确认后清空所有商品
   */
  const clearCart = () => {
    Taro.showModal({
      title: '提示',
      content: '确定要清空购物车吗？',
      success: (res) => {
        if (res.confirm) {
          dispatch({ type: 'CLEAR_CART' })
        }
      }
    })
  }
  
  /**
   * 处理订单备注输入
   * @param e 输入事件对象
   */
  const handleNoteChange = (e) => {
    setNote(e.detail.value)
  }
  
  // 使用积分
  const handleUsePoints = () => {
    if (!state.currentUser) {
      Taro.showToast({
        title: '请先登录',
        icon: 'none'
      })
      return
    }
    
    // 显示积分使用确认
    Taro.showModal({
      title: '使用积分',
      content: `当前可用积分: ${userPoints}点\n最多可抵扣: ¥${maxDiscount.toFixed(2)}\n确认使用${pointsToUse}积分抵扣¥${pointsDiscount.toFixed(2)}吗？`,
      confirmText: '确认使用',
      cancelText: '取消',
      success: (res) => {
        if (res.confirm) {
          setUsePoints(true)
        } else {
          setUsePoints(false)
          setPointsToUse(0)
        }
      }
    })
  }
  
  // 调整积分使用量
  const handleAdjustPoints = () => {
    Taro.showModal({
      title: '调整积分',
      content: `当前可用积分: ${userPoints}点\n最多可使用: ${maxPointsForOrder}点\n请输入要使用的积分数量(${pointsConfig.POINTS_USAGE_LIMITS.POINTS_USE_MULTIPLE}的倍数)`,
      editable: true,
      placeholderText: `${pointsToUse}`,
      success: (res) => {
        if (res.confirm && res.content) {
          const newPointsToUse = parseInt(res.content)
          
          // 验证输入
          if (isNaN(newPointsToUse)) {
            Taro.showToast({
              title: '请输入有效数字',
              icon: 'none'
            })
            return
          }
          
          // 验证是否是指定倍数
          if (newPointsToUse % pointsConfig.POINTS_USAGE_LIMITS.POINTS_USE_MULTIPLE !== 0) {
            Taro.showToast({
              title: `积分必须是${pointsConfig.POINTS_USAGE_LIMITS.POINTS_USE_MULTIPLE}的倍数`,
              icon: 'none'
            })
            return
          }
          
          // 验证范围
          if (newPointsToUse < 0) {
            Taro.showToast({
              title: '积分不能为负数',
              icon: 'none'
            })
            return
          }
          
          if (newPointsToUse > maxPointsForOrder) {
            Taro.showToast({
              title: `最多可使用${maxPointsForOrder}积分`,
              icon: 'none'
            })
            setPointsToUse(maxPointsForOrder)
            return
          }
          
          if (newPointsToUse > userPoints) {
            Taro.showToast({
              title: '积分不足',
              icon: 'none'
            })
            return
          }
          
          // 更新积分使用量
          setPointsToUse(newPointsToUse)
          setUsePoints(newPointsToUse > 0)
        } else if (res.cancel) {
          // 用户取消，不做任何改变
        }
      }
    })
  }
  
  // 处理结算
  const handleCheckout = async () => {
    if (state.cart.length === 0) {
      Taro.showToast({
        title: '购物车为空',
        icon: 'none'
      })
      return
    }
    
    if (!state.currentUser) {
      Taro.showToast({
        title: '请先登录',
        icon: 'none'
      })
      return
    }
    
    if (!isOnline) {
      Taro.showToast({
        title: '离线状态无法下单',
        icon: 'none'
      })
      return
    }
    
    setSubmitting(true)
    
    try {
      // 创建订单
      const orderData = {
        userId: state.currentUser.id,
        userName: state.currentUser.name,
        items: state.cart,
        totalAmount,
        pointsUsed: usePoints ? pointsToUse : 0,
        finalAmount,
        status: 'pending',
        createdAt: new Date(),
        updatedAt: new Date(),
        note: note.trim() || undefined
      }
      
      // 如果使用积分，先扣减积分
      let pointsTransaction = null
      if (usePoints && pointsToUse > 0) {
        // 再次验证积分
        const hasEnough = await pointsUtils.hasEnoughPoints(state.currentUser.id, pointsToUse)
        if (!hasEnough) {
          Taro.showToast({
            title: '积分不足',
            icon: 'none'
          })
          setSubmitting(false)
          return
        }
        
        // 扣减积分
        pointsTransaction = await pointsUtils.usePoints(
          state.currentUser.id,
          pointsToUse,
          'order_payment',
          '订单积分抵扣',
          undefined // 订单ID稍后添加
        )
        
        if (!pointsTransaction.success) {
          Taro.showToast({
            title: pointsTransaction.error || '积分扣减失败',
            icon: 'none'
          })
          setSubmitting(false)
          return
        }
      }
      
      // 保存订单
      const orderId = await CloudDataManager.addData('orders', orderData)
      
      // 如果使用了积分，更新积分交易的关联订单ID
      if (pointsTransaction && pointsTransaction.transactionId) {
        await CloudDataManager.updateData('points_transactions', pointsTransaction.transactionId, {
          referenceId: orderId
        })
      }
      
      // 清空购物车
      dispatch({ type: 'CLEAR_CART' })
      
      // 提示成功
      Taro.showToast({
        title: '下单成功',
        icon: 'success'
      })
      
      // 跳转到订单详情页
      setTimeout(() => {
        Taro.navigateTo({
          url: `/pages/orders/detail?id=${orderId}`
        })
      }, 1500)
    } catch (error) {
      console.error('下单失败:', error)
      
      errorUtils.handleError(error, ErrorType.ORDER, {
        showToast: true,
        operation: 'createOrder',
        data: { userId: state.currentUser.id }
      })
    } finally {
      setSubmitting(false)
    }
  }
  
  // 处理网络状态变化
  const handleNetworkStatusChange = (online: boolean) => {
    setIsOnline(online)
  }
  
  return (
    <View className='cart'>
      {/* 网络状态提示 */}
      <NetworkStatus onStatusChange={handleNetworkStatusChange} />
      
      {/* 购物车为空提示 */}
      {state.cart.length === 0 ? (
        <View className='empty-cart'>
          <Text className='empty-text'>购物车为空</Text>
          <Button 
            className='go-shopping-btn'
            onClick={() => Taro.navigateTo({ url: '/pages/index/index' })}
          >
            去选购
          </Button>
        </View>
      ) : (
        <>
          {/* 购物车商品列表 */}
          <ScrollView scrollY className='cart-items'>
            {state.cart.map(item => (
              <View key={item.dishId} className='cart-item'>
                <View className='item-info'>
                  <Text className='item-name'>{item.dishName}</Text>
                  <Text className='item-price'>¥{item.price.toFixed(2)}</Text>
                </View>
                
                <View className='item-actions'>
                  <View className='quantity-control'>
                    <Button 
                      className='quantity-btn minus'
                      onClick={() => updateItemQuantity(item.dishId, item.quantity - 1)}
                    >
                      -
                    </Button>
                    <Text className='quantity'>{item.quantity}</Text>
                    <Button 
                      className='quantity-btn plus'
                      onClick={() => updateItemQuantity(item.dishId, item.quantity + 1)}
                    >
                      +
                    </Button>
                  </View>
                  
                  <Text 
                    className='remove-btn'
                    onClick={() => removeItem(item.dishId)}
                  >
                    删除
                  </Text>
                </View>
                
                <Text className='item-total'>小计: ¥{item.totalPrice.toFixed(2)}</Text>
              </View>
            ))}
          </ScrollView>
          
          {/* 备注 */}
          <View className='note-section'>
            <Text className='note-label'>订单备注:</Text>
            <Textarea
              className='note-input'
              value={note}
              onInput={handleNoteChange}
              placeholder='请输入备注信息（可选）'
              maxlength={200}
            />
          </View>
          
          {/* 清空购物车按钮 */}
          <View className='clear-cart'>
            <Button className='clear-btn' onClick={clearCart}>
              清空购物车
            </Button>
          </View>
          
          {/* 积分使用区域 */}
          {state.currentUser && userPoints > 0 && (
            <View className='points-section'>
              <View className='points-header'>
                <Text className='points-title'>积分抵扣</Text>
                <Text className='points-available'>可用积分: {userPoints}</Text>
              </View>
              
              {usePoints ? (
                <View className='points-active'>
                  <View className='points-info'>
                    <Text className='points-value'>使用 {pointsToUse} 积分</Text>
                    <Text className='points-discount'>抵扣 ¥{pointsDiscount.toFixed(2)}</Text>
                  </View>
                  <View className='points-actions'>
                    <Text className='adjust-link' onClick={handleAdjustPoints}>调整</Text>
                    <Text className='cancel-link' onClick={() => { setUsePoints(false); setPointsToUse(0); }}>取消</Text>
                  </View>
                </View>
              ) : (
                <Button 
                  className='use-points-button' 
                  onClick={handleUsePoints}
                  disabled={maxPointsForOrder < pointsConfig.POINTS_USAGE_LIMITS.MIN_POINTS_TO_USE}
                >
                  {maxPointsForOrder >= pointsConfig.POINTS_USAGE_LIMITS.MIN_POINTS_TO_USE
                    ? `使用${maxPointsForOrder}积分抵扣¥${maxDiscount.toFixed(2)}`
                    : `订单金额过小，无法使用积分`}
                </Button>
              )}
            </View>
          )}
          
          {/* 结算区域 */}
          <View className='checkout-section'>
            <View className='price-summary'>
              <View className='price-row'>
                <Text className='price-label'>商品金额</Text>
                <Text className='price-value'>¥{totalAmount.toFixed(2)}</Text>
              </View>
              
              {usePoints && (
                <View className='price-row discount'>
                  <Text className='price-label'>积分抵扣</Text>
                  <Text className='price-value'>-¥{pointsDiscount.toFixed(2)}</Text>
                </View>
              )}
              
              <View className='price-row total'>
                <Text className='price-label'>实付金额</Text>
                <Text className='price-value'>¥{finalAmount.toFixed(2)}</Text>
              </View>
            </View>
            
            <Button 
              className='checkout-button' 
              disabled={state.cart.length === 0 || submitting || !isOnline}
              loading={submitting}
              onClick={handleCheckout}
            >
              结算
            </Button>
          </View>
        </>
      )}
      
      {/* 离线提示 */}
      {!isOnline && (
        <View className='offline-warning'>
          <Text>您当前处于离线状态，无法下单</Text>
        </View>
      )}
    </View>
  )
}

export default Cart 